<template>
  <a-drawer
    :title="title"
    :maskClosable="true"
    width="650"
    placement="right"
    :closable="true"
    @close="close"
    :visible="visible"
    style="overflow: auto;padding-bottom: 53px;">

    <a-form>
      <a-row>
        <span v-if="appData.length>0">
          <a-col :span="11" style="margin-right:8px">
            <a-form-item>
              <a-card title="所拥有的应用权限" >
                <a-tree
                  checkable
                  @check="onAppCheck"
                  :treeData="appData"
                  :checkedKeys="checkedAppKeys"
                  @select="onAppSelect"
                  :checkStrictly="checkAppStrictly"
                  :selectedKeys="selectedAppKeys"
                  :replaceFields="appDataFileds"
                  style="height:680px;overflow: auto;"/>
              </a-card>
            </a-form-item>
          </a-col>
          <a-col :span="11">
            <a-form-item >
              <a-card title="所拥有的部门权限">
                <a-tree
                  v-if="permissionData.length>0"
                  checkable
                  :checkedKeys="checkedPermission"
                  :treeData="permissionData"
                  :selectedKeys="selectedKeys"
                  @check="onCheckPermission"
                  @select="onTreeNodeSelect"
                  :defaultExpandAll="defaultExpandAll"
                  style="height:680px;overflow: auto;">
                  <span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
                    {{ slotTitle }}<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
                  </span>
                </a-tree>
              </a-card>
            </a-form-item>
          </a-col>
        </span>
        <div v-else><h3>无可配置部门权限!</h3></div>
      </a-row>
    </a-form>

    <div class="drawer-bootom-button">
      <!-- <a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
        <a-menu slot="overlay">
          <a-menu-item key="3" @click="checkALL">全部勾选</a-menu-item>
          <a-menu-item key="4" @click="cancelCheckALL">取消全选</a-menu-item>
          <a-menu-item key="5" @click="expandAll">展开所有</a-menu-item>
          <a-menu-item key="6" @click="closeAll">合并所有</a-menu-item>
        </a-menu>
        <a-button>
          树操作 <a-icon type="up" />
        </a-button>
      </a-dropdown> -->
      <a-popconfirm title="确定放弃编辑？" @confirm="close" okText="确定" cancelText="取消">
        <a-button style="margin-right: .8rem">取消</a-button>
      </a-popconfirm>
      <a-button @click="handleSubmit(true)" type="primary" :loading="loading">保存</a-button>
    </div>
    <dept-role-datarule-modal ref="datarule"></dept-role-datarule-modal>
  </a-drawer>

</template>
<script>
  import RoleDataruleModal from '@/views/system/role/modules/RoleDataruleModal.vue'
  import DeptRoleDataruleModal from './DeptRoleDataruleModal.vue'
  import { removeArray } from '@/utils/util.js'
  import { JeecgListMixin } from '@/mixins/JeecgListMixin.js'
  import { queryAppTreeByDepartRole, queryDepartAppPermissionTree, queryDepartPermissionByRoleId, saveDeptRoleAppPermission } from '@views/system/myDepart/role/service';

  export default {
    name: 'DeptRoleAuthModal',
    components: {
      DeptRoleDataruleModal,
      RoleDataruleModal
    },
    mixins: [JeecgListMixin],
    data() {
      return {
        departId: '',
        roleId: '',
        tenantId: this.getTenantId(),
        treeData: [],
        defaultCheckedKeys: [],
        checkedKeys: [],

        defaultExpandAll: true,
        autoExpandParent: true,
        checkStrictly: true,
        title: '部门角色权限配置',
        visible: false,
        loading: false,

        /** 应用列表 */
        appData: [],
        checkedAppKeys: [],
        selectedAppKeys: [],
        checkAppStrictly: false,
        delAppkeys: [], // 删除的AppKey
        appDataFileds: {
          title: 'appName',
          key: 'appId'
        },

        /** 应用授权 */
        permissionData: [],
        checkedPermission: [],
        selectedKeys: [],
        autoExpandParentPermission: true,
        allTreeKeys: [],
        expandedKeysAll: [],
        appPermissionMap: new Map(),
        selectedApp: {},
        requestedAppIds: [],
        halfCheckedKeys: []
      }
    },
    watch: {
      visible () {
        if (this.visible) {
          this.loadData();
        }
      }
    },
    methods: {
      switchCheckStrictly (v) {
        if (v === 1) {
          this.checkStrictly = false
        } else if (v === 2) {
          this.checkStrictly = true
        }
      },
      onTreeNodeSelect(id) {
        if (id && id.length > 0) {
          this.selectedKeys = id
        }
        this.$refs.datarule.show(this.selectedKeys[0], this.departId, this.roleId)
      },
      show(roleId, departId) {
        this.departId = departId
        this.roleId = roleId
        this.visible = true;
      },
      close () {
        this.reset()
        this.$emit('close');
        this.visible = false;
      },
      onExpand(expandedKeys) {
        this.expandedKeysAll = expandedKeys;
        this.autoExpandParent = false
      },
      reset () {
        this.expandedKeysAll = []
        this.checkedKeys = []
        this.defaultCheckedKeys = []
        this.halfCheckedKeys = []
        this.appData = []
        this.checkedAppKeys = []
        this.selectedAppKeys = []
        this.delAppkeys = []
        this.permissionData = []
        this.checkedPermission = []
        this.selectedKeys = []
        this.allTreeKeys = []
        this.appPermissionMap.clear()
        this.selectedApp = {}
        this.loading = false
        this.requestedAppIds = []
      },
      expandAll () {
        this.expandedKeysAll = this.allTreeKeys
      },
      closeAll () {
        this.expandedKeysAll = []
      },
      checkALL () {
        this.checkedPermission = this.allTreeKeys
      },
      cancelCheckALL () {
        this.checkedPermission = []
      },
      handleCancel () {
        this.close()
      },
      handleSubmit(exit) {
         let that = this;
        let params = {
          tenantId: that.tenantId,
          departId: that.departId,
          roleId: that.roleId,
          roleApps: [],
          delRoleApps: []
        }
         let selectedApp = [];
        // 添加删除的
        if (that.delAppkeys && that.delAppkeys.length > 0) {
            that.delAppkeys.forEach(key => {
              that.appData.forEach(function(roleApp) {
              if (roleApp.appId === key) {
                params.delRoleApps.push({ 'roleId': that.roleId, 'appId': roleApp.appId, 'departId': that.departId });
              }
              });
            });
        }
        // 获取已选应用中的列表
         if (that.checkedAppKeys && that.checkedAppKeys.length > 0) {
            that.checkedAppKeys.forEach(function(element) {
              that.appData.forEach(function(roleApp) {
                  if (roleApp.appId === element) {
                    selectedApp.push(roleApp);
                  }
              });
            });
          }
          selectedApp.forEach(function(roleApp) {
            let key = roleApp.appId;
            let appPermission = that.appPermissionMap.get(key)
            if (appPermission) {
              appPermission.permissionIds = [...appPermission.permissionIds, ...appPermission.halfPermissionIds]
              params.roleApps.push({ 'roleId': that.roleId, 'appId': roleApp.appId, 'departId': that.departId, 'appPermissions': appPermission });
            } else {
              params.roleApps.push({ 'roleId': that.roleId, 'appId': roleApp.appId, 'departId': that.departId });
            }
          });

        that.loading = true;
        console.log('请求参数：', params);
        saveDeptRoleAppPermission(params).then((res) => {
          if (res.success) {
            that.$message.success(res.message);
            that.loading = false;
             that.close()
          } else {
            that.$message.error(res.message);
            that.loading = false;
          }
        })
      },
      convertTreeListToKeyLeafPairs(treeList, keyLeafPair = []) {
        for (const { key, leaf, children } of treeList) {
          keyLeafPair.push({ key, leaf })
          if (children && children.length > 0) {
            this.convertTreeListToKeyLeafPairs(children, keyLeafPair)
          }
        }
        return keyLeafPair;
      },
      loadData() {
         this.loadAppData();
      },
      /** 应用权限 *******************================> */
      loadPermissionData(tenantId, selectedApp) {
        if (selectedApp && selectedApp.appId) {
          let params = {
            'tenantId': tenantId,
            departId: this.departId,
            appId: selectedApp.appId
          }
          queryDepartAppPermissionTree(selectedApp.appId, params).then((res) => {
            this.permissionData = res.result.treeList
            this.allTreeKeys = res.result.ids
            let isRequested = this.requestedAppIds.findIndex(key => key === selectedApp.appId) !== -1;
            if (isRequested) {
              let permissionIds = this.getPermissionIdsByKey(selectedApp.appId)
              let halfPermissionIds = this.getHalfPermissionsIdsByKey(selectedApp.appId)
              this.checkedPermission = [...permissionIds];
              this.defaultCheckedKeys = [...permissionIds];
              this.halfCheckedKeys = [...halfPermissionIds];
              return;
            }
            const keyLeafPairs = this.convertTreeListToKeyLeafPairs(this.permissionData)
            let params = {
              tenantId: this.tenantId,
              departId: this.departId,
              roleId: this.roleId,
              appId: selectedApp.appId
            };

            queryDepartPermissionByRoleId(selectedApp.appId, params).then((res) => {
              if (res.success) {
                  this.requestedAppIds.push(selectedApp.appId);
                  if (res.result && res.result.length > 0) {
                    // 过滤出 leaf node 即可，即选中的
                    // Tree组件中checkStrictly默认为false的时候，选中子节点，父节点会自动设置选中或半选中
                    // 保存 checkedKeys 以及 halfCheckedKeys 以便于未做任何操作时提交表单数据
                    const checkedPermissionKeys = [...res.result].filter(key => {
                      const keyLeafPair = keyLeafPairs.filter(item => String(item.key) === String(key))[0]
                      return keyLeafPair && keyLeafPair.leaf
                    })
                    const halfCheckedPermissionKeys = [...res.result].filter(key => {
                      const keyLeafPair = keyLeafPairs.filter(item => String(item.key) === String(key))[0]
                      return keyLeafPair && !keyLeafPair.leaf
                    })
                    this.checkedPermission = [...checkedPermissionKeys];
                    this.halfCheckedKeys = [...halfCheckedPermissionKeys];
                    this.defaultCheckedKeys = [...halfCheckedPermissionKeys, ...checkedPermissionKeys];
                    this.expandedKeysAll = this.allTreeKeys;
                    this.setAppPermission(selectedApp, this.checkedPermission, this.halfCheckedKeys);
                    // console.log(this.appPermissionMap);
                  } else {
                    this.checkedPermission = [];
                    this.halfCheckedKeys = [];
                    this.defaultCheckedKeys = [];
                    this.expandedKeysAll = this.allTreeKeys;
                  }
              }
            })
          })
       }
      },
      onCheckPermission (checkedPermission, { halfCheckedKeys }) {
          this.checkedPermission = checkedPermission
          this.halfCheckedKeys = halfCheckedKeys
          this.setAppPermission(this.selectedApp, this.checkedPermission, this.halfCheckedKeys)
          // console.log(this.checkedPermission);
          // console.log(this.appPermissionMap);
          // console.log('=======================>');
          // console.log(this.halfCheckedKeys);
        },

      /** * 应用 ******************=====================>  */
      loadAppData() {
          let params = {
              tenantId: this.tenantId,
              departId: this.departId,
              roleId: this.roleId
            };
            if (this.departId && this.roleId) {
                queryAppTreeByDepartRole(params).then((res) => {
                  if (res.success) {
                    this.appData = [...res.result.appList];
                    this.checkedAppKeys = [...res.result.authAppIds];
                    this.setAppChecked(this.checkedAppKeys);
                    // console.log(this.appPermissionMap);
                  } else {
                  }
                }).finally(() => {})
            }
        },
        onAppSelect(selectedKeys, e) {
          let that = this;
          this.selectedAppKeys = selectedKeys;
          if (selectedKeys) {
            let selectedApp = {}
            let curKey = selectedKeys[0];
            that.appData.forEach(function (item) {
            if (curKey === item.appId) {
                selectedApp = item;
                return true;
              }
            })
            if (selectedApp) {
              that.selectedApp = selectedApp;
              this.loadPermissionData(this.tenantId, that.selectedApp);
            }
          }
        },
      onAppCheck (checkedKeys, e) {
        if (this.checkAppStrictly) {
          this.checkedAppKeys = [].concat(checkedKeys.checked[checkedKeys.checked.length - 1]);
        } else { // 可多选
          this.checkedAppKeys = checkedKeys;
        }
        let appKey = e.node.eventKey;
        // 获取当前点击的appId 即 key
        // 取消
        if (!e.checked) {
          this.delAppkeys.push(appKey);
        } else { // 如果选中 从列表中删除
          removeArray(this.delAppkeys, appKey)
        }
        // console.log(this.checkedAppKeys);
        // console.log(this.delAppkeys);
      },
      /** 保存数据集合处理 */
      setAppPermission (selectedApp, pPermissionIds, halfCheckedKeys) {
        let obj = {
          roleId: this.roleId,
          appId: selectedApp.appId,
          departId: this.departId,
          permissionIds: pPermissionIds,
          halfPermissionIds: halfCheckedKeys
        }
        let key = this.getKey(selectedApp.appId);
        if (this.appPermissionMap.has(key)) {
            this.appPermissionMap.get(key).permissionIds = [...pPermissionIds];
            this.appPermissionMap.get(key).halfPermissionIds = [...halfCheckedKeys];
        } else {
          this.appPermissionMap.set(key, obj);
        }
      },
      setAppChecked (checkedAppKeys) {
        if (checkedAppKeys && checkedAppKeys.length > 0) {
          checkedAppKeys.forEach(element => {
            this.appData.forEach(app => {
              if (app.key === element) {
                // 存入map
                if (!this.appPermissionMap.has(element)) {
                  this.setAppPermission(app, [], []);
                }
              }
            });
          });
        }
      },
      getKey(appId) {
        return String(appId);
      },
      getPermissionIdsByKey(key) {
        let appPermission = this.appPermissionMap.get(key)
        if (appPermission) {
          return appPermission.permissionIds;
        }
        return [];
      },
      getHalfPermissionsIdsByKey(key) {
        let appPermission = this.appPermissionMap.get(key)
        if (appPermission) {
          return appPermission.halfPermissionIds;
        }
        return [];
      }

    }
  }

</script>
<style lang="less" scoped>
  .drawer-bootom-button {
    position: absolute;
    bottom: 0;
    width: 100%;
    border-top: 1px solid #e8e8e8;
    padding: 10px 16px;
    text-align: right;
    left: 0;
    background: #fff;
    border-radius: 0 0 2px 2px;
  }

</style>
